package com.example.commom.util.remote;

import com.alibaba.fastjson.JSON;
import com.example.commom.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: bebm
 * @date: 2022/4/2 17:04
 * @description:
 */
@Slf4j
public abstract class AbstractRemoteTransferChain implements RemoteTransferChain{

    protected List<RemoteProperties> remoteProperties;

    /**
     *
     * @param remoteTransferHandler
     * @param remoteRollbackHandler
     * @return
     */
    @Override
    public RemoteTransferChain next(RemoteTransferHandler remoteTransferHandler,RemoteRollbackHandler remoteRollbackHandler){
        if(CollectionUtils.isEmpty(remoteProperties)){
            remoteProperties= new ArrayList<>();
        }
        remoteProperties.add(new RemoteProperties(remoteTransferHandler,remoteRollbackHandler));
        return this;
    }

    @Override
    public RemoteTransferChain nextBeforeCallback(RemoteTransferCallbackHandler remoteTransferCallbackHandler, RemoteRollbackHandler remoteRollbackHandler) {
        return nextBeforeCallback(remoteTransferCallbackHandler,remoteRollbackHandler,1);
    }

    @Override
    public RemoteTransferChain nextBeforeCallback(RemoteTransferCallbackHandler remoteTransferCallbackHandler, RemoteRollbackHandler remoteRollbackHandler, Integer resultIndex) {
        if (null == remoteProperties) {
            remoteProperties = new ArrayList<>();
        }
        remoteProperties.add(new RemoteProperties(remoteTransferCallbackHandler, remoteRollbackHandler, resultIndex));
        return this;
    }

    @Override
    public <T> T getExecuteResult(int index, Class<T> clz) {
        RemoteProperties remoteProtection = remoteProperties.get(index);
        if (StringUtils.isEmpty(remoteProtection.getResult())) {
            return null;
        }
        return JSON.parseObject(remoteProtection.getResult(), clz);
    }


    protected void rollback(int i) {
        if (i != 0) {
            for (int j = 0; j < i; j++) {
                RemoteProperties remoteProtection = remoteProperties.get(j);
                RemoteRollbackHandler remoteRollbackHandler=remoteProtection.getRemoteRollbackHandler();
                if (remoteRollbackHandler != null) {
                    remoteRollbackHandler.rollback();
                }
            }
        }
        log.error("call error,rollback from index:[{}]", i);
        throw new BizException("call error");
    }


}
